package com.cneport.das.client.trans.service;

import com.cneport.das.client.conf.TransConf;
import com.cneport.das.common.model.trans.*;
import com.cneport.das.common.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.io.File;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * das 客户端（传输）
 *
 * @Author GavinZhang
 * @date 2021-12-20 10:06:44
 */
@Service
@Slf4j
public class TransClientService {

    @Autowired
    private com.cneport.das.client.conf.ClientConfCache clientConfCache;

    /**
     * 发送报文
     *
     * @param erpPutRequest
     * @return
     * @throws DasClientException
     */
    public String putMsg(ErpPutRequest erpPutRequest) {
        final String ver = "1.0";
        ErpPutRequest.ReqHead reqHead = erpPutRequest.getReqHead();
        String corpNo = reqHead.getCopNo();
        String guid = reqHead.getGuid();
        TransConf configByCorpNo = clientConfCache.getTransConfigByCorpNo(corpNo);
        if (configByCorpNo == null) {
            return fail(guid, "-1", "没有相关公司 " + corpNo + " 的配置文件信息！");
        }
        String licence = configByCorpNo.getLicence();
        ClientPutRequest clientPutRequest = new ClientPutRequest();
        ClientPutRequest.ReqHead clientReqeustHead = ClientPutRequest.ReqHead.builder()
                .guid(guid).ver(ver).msgType(reqHead.getMsgType()).copMsgId(reqHead.getCopMsgId())
                .receiverIds(reqHead.getReceiverIds()).reqTime(DateUtil.C14()).senderId(reqHead.getSenderId())
                .copNo(reqHead.getCopNo()).copLic(licence)
                .build();

        clientPutRequest.setReqHead(clientReqeustHead);

        ErpPutRequest.ReqData reqData = erpPutRequest.getReqData();
        String data = reqData.getData();
        String trans = reqData.getTrans();

        ClientPutRequest.ReqData clientReqData = ClientPutRequest.ReqData.builder()
                .trans(trans)
                .encoderVer(configByCorpNo.getEncoderVer())
                .data(data)
                .build();
        clientPutRequest.setReqData(clientReqData);


        String path = clientConfCache.getPriEncoderPath(corpNo);
        File file = new File(path);
        if (file.exists()) {
            //加密
            clientPutRequest = EncryptUtil.encode(clientPutRequest, path, true);
        } else {
            log.error("秘钥不存在！ " + path);
            return fail(guid, "-1", "秘钥不存在！");
        }
        clientPutRequest.setAddInfos(erpPutRequest.getAddInfos());
        //签名
        clientPutRequest = SignUtil.sign(clientPutRequest);

        String reqXml = JAXBUtils.obj2Xml(clientPutRequest);
        //转码
        try {
            reqXml = URLEncoder.encode(reqXml, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }

        //发送
        String url = clientConfCache.getServerServiceUrl() + "/putServerMsg";
        try {
            String response = HttpUtils.post(url, reqXml, new HashMap());
            ClientPutResponse cpr = JAXBUtils.xml2Obj(ClientPutResponse.class, response);
            ClientPutResponse.RespHead respHead = cpr.getRespHead();
            if ("-1".equals(respHead.getRespCode())) {
                return fail(guid, respHead.getRespCode(), respHead.getRespMsg());
            }
        } catch (Exception e) {
            e.printStackTrace();
            return fail(guid, "-1", "调用DAS server失败！");
        }
        return success(guid, erpPutRequest.getAddInfos());
    }


    public String query(ErpGetRequest erpGetRequest) {
        ErpGetRequest.ReqHead reqHead = erpGetRequest.getReqHead();
        AddInfos addInfos = erpGetRequest.getAddInfos();

        String corpNo = reqHead.getCopNo();
        String guid = reqHead.getGuid();
        TransConf corpByCorpNo = clientConfCache.getTransConfigByCorpNo(corpNo);
        if (corpByCorpNo == null) {
            return fail(guid, "-1", "没有相关公司 " + corpNo + " 的配置文件信息！");
        }
        ClientGetRequest clientGetRequest = new ClientGetRequest();
        ClientGetRequest.ReqHead clientGetHead = ClientGetRequest.ReqHead.builder()
                .guid(guid).copNo(corpNo).copLic(corpByCorpNo.getLicence())
                .encoderVer(corpByCorpNo.getEncoderVer()).senderId(corpByCorpNo.getSenderId())
                .reqTime(DateUtil.C14()).maxCnt(reqHead.getMaxCnt()).build();
        clientGetRequest.setReqHead(clientGetHead);
        clientGetRequest.setAddInfos(addInfos);
        //加密
        String keyPath = clientConfCache.getPriEncoderPath(corpNo);
        File file = new File(keyPath);
        if (file.exists()) {
            clientGetRequest = EncryptUtil.encode(clientGetRequest, keyPath, true);
        } else {
            log.error("秘钥不存在！ " + keyPath);
            return fail(guid, "-1", "秘钥不存在！");
        }
        //加签
        clientGetRequest = SignUtil.sign(clientGetRequest);

        String para = JAXBUtils.obj2Xml(clientGetRequest).trim();
        log.info("请求报文：\n" + para);
        try {
            para = URLEncoder.encode(para, "UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        //发送
        String url = clientConfCache.getServerServiceUrl() + "/getServerMsg";

        try {

            String response = HttpUtils.post(url, para, new HashMap());

            ClientGetResponse clientGetResponse = JAXBUtils.xml2Obj(ClientGetResponse.class, response);
            if (clientGetResponse == null || clientGetResponse.getRespData() == null) {
                return fail(guid, "0", "暂时没有您需要的信息！");
            }

            ErpGetResponse erpGetResponse = new ErpGetResponse();

            List<String> datas = clientGetResponse.getRespData().getData();


            //解密
            datas = EncryptUtil.decode(datas, keyPath, true);
            //组装
            erpGetResponse.setRespData(new RespData(datas));
            erpGetResponse.setRespHead(ErpGetResponse.RespHead.builder()
                    .guid(guid).respCode("0").respTime(DateUtil.C14())
                    .build());
            erpGetResponse.setAddInfos(clientGetResponse.getAddInfos());
            return JAXBUtils.obj2Xml(erpGetResponse);

        } catch (Exception e) {
            e.printStackTrace();
            return fail(guid, "-1", "调用DAS server失败！");
        }
    }

    public String getMsgBySchedule(String guid, String copNo, String copLic, Integer maxCnt, String encoderVer) {
        //需要加密 copLic
        String keyPath = clientConfCache.getPriEncoderPath(copNo);
        File file = new File(keyPath);
        if (file.exists()) {
            copLic = SecurityUtils.encode(keyPath, copLic, true);
        } else {
            log.error("秘钥不存在！ " + keyPath);
            return "";
        }

        Map<String, String> param = new HashMap();
        param.put("guid", guid);
        param.put("copNo", copNo);
        param.put("copLic", copLic);
        param.put("maxCnt", maxCnt + "");
        param.put("encoderVer", encoderVer);

        //发送
        String url = clientConfCache.getServerServiceUrl() + "/getMsgByClientProxy";
        try {
            String response = HttpUtils.get(url, param, new HashMap<>());
            ClientGetResponse respData = JAXBUtils.xml2Obj(ClientGetResponse.class, response);
            if (respData == null || respData.getRespData() == null) {
                return "";
            }
            List<String> data = respData.getRespData().getData();
            data = EncryptUtil.decode(data, keyPath, true);
            //返回的是已经解密过的
            respData.setRespData(new RespData(data));
            return JAXBUtils.obj2Xml(respData);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("client-->Server 调用异常");
        }

        return "";
    }

    private String success(String guid, AddInfos addInfos) {
        ErpPutResponse.RespHead head = ErpPutResponse.RespHead.builder()
                .reqGuid(guid)
                .respCode("0")
                .respMsg("")
                .respTime(DateUtil.C14())
                .build();
        ErpPutResponse response = new ErpPutResponse();
        response.setRespHead(head);
        response.setAddInfos(addInfos);
        return JAXBUtils.obj2Xml(response);

    }

    private String fail(String guid, String code, String msg) {
        ErpPutResponse.RespHead head = ErpPutResponse.RespHead.builder()
                .reqGuid(guid)
                .respCode(code)
                .respMsg(msg)
                .respTime(DateUtil.C14())
                .build();
        ErpPutResponse response = new ErpPutResponse();
        response.setRespHead(head);
        return JAXBUtils.obj2Xml(response);
    }

    @PostConstruct
    public String sign() {
        String mac = IPUtil.getLocalMac();
        String ip = IPUtil.getLocalIP();
        Set<String> copNoes = clientConfCache.getAllCorpNo();
        if (copNoes != null && copNoes.size() > 0) {
            StringBuilder sb = new StringBuilder();
            for (String copNo : copNoes) {
                sb.append(copNo + "#");
            }
            String cops = sb.toString();
            cops = cops.substring(0, cops.length() - 1);
            //发送
            String url = clientConfCache.getServerServiceUrl() + "/regist";
            Map<String, String> param = new HashMap();
            param.put("ip", ip);
            param.put("mac", mac);
            param.put("corpNoStr", cops);
            try {
                String rest = HttpUtils.get(url, param, new HashMap<>());
                if ("-1".equals(rest)) {
                    log.error("登记时服务器端发生了异常!");
                }
            } catch (Exception e) {
                log.error("登记时发生了异常:" + e.getLocalizedMessage());
            }
        }
        return null;
    }
}
